﻿using BCCommon;
using BCCommon.TMS.Order;
using BCEntity.TMS.Order.OrderCancelRecord;
using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BCData.TMS.Order.OrderCancelRecord
{
    public class OrderCancelRecordData : IOrderCancelRecordData
    {
        private readonly IDatabaseContext databaseContext;
        private const string QUERY_VIEW = @"SELECT L.OrderCancelRecordId,L.CancelOrderPromising,L.CancelStatus,L.CreateTime,L.ValidationRemark,L.AdminId,L.AdminFullName,L.CancelOrderTime,L.CancelOrderPerson,
                                            L.OrderId,L.OrderNo,A.UserId,A.Shipping,A.ShippingPhone,A.IsVip,A.IsBook,A.BusinessType,A.VehicleTypeId,A.VehicleCategoryReferenceId,
		                                    A.PayMode,A.ProvinceId,A.CommunityId,A.CountyId,A.GoodsPhoto,A.GoodsName,A.GoodsWeight,A.GoodsVolume,A.GoodsLength,A.GoodsWidth,
		                                    A.GoodsHeight,A.BookTime,A.CompleteTime,A.DriverRemark,A.DriverId,A.VehicleNo,A.OrderStatus,A.NotifyDriveTime,A.VehicleStartOutTime,
		                                    A.ShippingPayTime,A.ConsigneePayTime,A.IsUnLoading,A.IsInsuredPrice,A.IsCod,A.IsReceipt,A.IsInsuredPriceHigh,A.IsNegotiatedPrice,A.IsInvoice,
		                                    A.InsuredPriceCertificates,A.InsuredPrice,A.InsuredPriceCharge,A.IsInsuredPriceHigh,A.MapTruckTypeId,A.MapTruckModeId,A.InvoiceAmount,
		                                    A.InsuredClaimWeight,A.InsuredClaimCount,A.InsuredClaimPay,A.CodCost,A.CodCharge,A.CodGoodsValueCertificates,A.ShippingIdentityCardNo,
		                                    A.ReceiptPhoto,A.ReceiptAcceptancePhoto,A.OrderAmount,A.InsuredPriceAmount,A.InsuredPriceChargeAmount,A.IsSettlement,A.DriverIdentityCardNo,
		                                    A.TimeoutClaimPayAmount,A.InsuredClaimPayAmount,A.CodCostAmount,A.CodChargeAmount,A.FreightCostAmount,A.TotalDistanceLength,A.IsCashPay,
		                                    A.VipExtraCostAmount,A.DriveOrderPromising,A.CloseOrderTime,A.CloseOrderContent,A.VehicleTypeName,A.VehicleCategoryName,
                                            H.Avatar AS ShippingAvatar,A.DriverName,A.DriverPhone
                                    FROM OrderCancelRecord L
                                    INNER JOIN `Orders` A ON A.OrderId=L.OrderId
                                    LEFT JOIN `User` H ON A.UserId=H.UserId;";
        public OrderCancelRecordData(IDatabaseContext databaseContext)
        {
            this.databaseContext = databaseContext;
        }

        public async Task<OrderCancelRecordEntity> Add(OrderCancelRecordEntity entity)
        {
            string sql = SqlCommands.GetInsertSql("OrderCancelRecord", new string[] { "OrderId", "DriverId", "OrderNo", "CancelOrderPromising", "CancelOrderPerson", "CancelStatus" });
            sql = string.Format("{0} {1} WHERE L.OrderCancelRecordId=LAST_INSERT_ID()", sql, QUERY_VIEW);
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?OrderId", entity.OrderId, DbType.Int64);
            parameters.Add("?DriverId", entity.DriverId, DbType.Int64);
            parameters.Add("?OrderNo", entity.OrderNo, DbType.AnsiString);
            parameters.Add("?CancelOrderPromising", entity.CancelOrderPromising, DbType.AnsiString);
            parameters.Add("?CancelOrderPerson", entity.CancelOrderPerson, DbType.AnsiString);
            parameters.Add("?CancelStatus", entity.CancelStatus.ToString(), DbType.AnsiString);
            return await this.databaseContext.Master.QueryFirstOrDefaultAsync<OrderCancelRecordEntity>(sql, parameters);
        }

        public async Task<OrderCancelRecordEntity> Get(long orderCancelRecordId)
        {
            string sql = string.Format("{0} WHERE L.OrderCancelRecordId=?OrderCancelRecordId", QUERY_VIEW);
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?OrderCancelRecordId", orderCancelRecordId, DbType.Int64, size: 20);
            return await this.databaseContext.Slave.QueryFirstOrDefaultAsync<OrderCancelRecordEntity>(sql, parameters);
        }

        public async Task<(IEnumerable<OrderCancelRecordEntity>, int)> Query(long? userId, long? agentRecordId, long? driverId, string orderNo, string vehicleNo, string driverName, OrderValidationStatus? cancelStatus, DateTime? start, DateTime? end, bool? ascending, int pageIndex, int pageSize)
        {
            List<string> wheres = new List<string>();
            DynamicParameters parameters = new DynamicParameters();
            if (userId.HasValue)
            {
                wheres.Add("A.UserId=?UserId");
                parameters.Add("?UserId", userId.Value, DbType.Int64, size: 20);
            }
            if (driverId.HasValue)
            {
                wheres.Add("A.DriverId=?DriverId");
                parameters.Add("?DriverId", driverId.Value, DbType.Int64, size: 20);
            }
            if (!string.IsNullOrWhiteSpace(orderNo))
            {
                wheres.Add("A.OrderNo=?OrderNo");
                parameters.Add("?OrderNo", orderNo, DbType.AnsiString, size: 50);
            }
            if (!string.IsNullOrWhiteSpace(vehicleNo))
            {
                wheres.Add("A.VehicleNo=?VehicleNo");
                parameters.Add("?VehicleNo", vehicleNo, DbType.AnsiString, size: 20);
            }
            if (!string.IsNullOrWhiteSpace(driverName))
            {
                wheres.Add("A.DriverName=?DriverName");
                parameters.Add("?DriverName", driverName, DbType.AnsiString, size: 20);
            }
            if (cancelStatus.HasValue)
            {
                wheres.Add("L.CancelStatus=?CancelStatus");
                parameters.Add("?CancelStatus", cancelStatus.ToString(), DbType.AnsiString);
            }
            if (start.HasValue && !end.HasValue)
            {
                wheres.Add("L.CreateTime>=?Start");
                parameters.Add("?Start", start.Value, DbType.DateTime);
            }
            else if (!start.HasValue && end.HasValue)
            {
                wheres.Add("L.CreateTime<=?End");
                parameters.Add("?End", end.Value, DbType.DateTime);
            }
            else if (start.HasValue && end.HasValue)
            {
                wheres.Add("L.CreateTime>=?Start AND L.CreateTime<=?End");
                parameters.Add("?Start", start.Value, DbType.DateTime);
                parameters.Add("?End", end.Value, DbType.DateTime);
            }
            if (agentRecordId.HasValue)
            {
                wheres.Add("A.AgentRecordId=?AgentRecordId");
                parameters.Add("?AgentRecordId", agentRecordId, DbType.Int64);
            }
            string sql = string.Format(@"{0} {1} GROUP BY L.OrderCancelRecordId ORDER BY L.CreateTime {4} LIMIT {2},{3}; 
                               SELECT Count(1) FROM OrderCancelRecord L
                                    INNER JOIN `Orders` A ON A.OrderId=L.OrderId
                                    LEFT JOIN `User` H ON A.UserId=H.UserId
                                    {1}",
                QUERY_VIEW,
                wheres.Count > 0 ? " WHERE " + string.Join(" AND ", wheres) : "",
                (pageIndex - 1) * pageSize, pageSize,
                ascending.HasValue && ascending.Value ? "ASC" : "DESC");
            return await this.databaseContext.Slave.QueryPageableListAsync<OrderCancelRecordEntity>(sql, parameters);
        }

        public async Task<OrderCancelRecordEntity> ValidationFail(OrderCancelRecordEntity entity)
        {

            string sql = SqlCommands.GetUpdateSql("OrderCancelRecord", new string[] { "CancelStatus", "ValidationRemark", "AdminId", "AdminFullName" }, new string[] { "DriverId", "OrderNo" });
            DynamicParameters parameters = new DynamicParameters();
            if (!entity.DriverId.HasValue)
            {
                sql = SqlCommands.GetUpdateSql("OrderCancelRecord", new string[] { "CancelStatus", "ValidationRemark", "AdminId", "AdminFullName" }, new string[] { "OrderNo" });
            }
            else
            {
                parameters.Add("?DriverId", entity.DriverId, DbType.Int64, size: 20);
            }

            parameters.Add("?OrderNo", entity.OrderNo, DbType.AnsiString, size: 20);
            parameters.Add("?OrderCancelRecordId", entity.OrderCancelRecordId, DbType.Int64, size: 20);
            parameters.Add("?CancelStatus", OrderValidationStatus.Fail.ToString(), DbType.AnsiString);
            parameters.Add("?ValidationRemark", entity.ValidationRemark, DbType.AnsiString, size: 400);
            parameters.Add("?AdminId", entity.AdminId, DbType.Int64, size: 20);
            parameters.Add("?AdminFullName", entity.AdminFullName, DbType.AnsiString, size: 400);
            sql = string.Format("{0} {1} WHERE OrderCancelRecordId=?OrderCancelRecordId", sql, QUERY_VIEW);
            return await this.databaseContext.Slave.QueryFirstOrDefaultAsync<OrderCancelRecordEntity>(sql, parameters);
        }

        public async Task<OrderCancelRecordEntity> ValidationSuccess(OrderCancelRecordEntity entity)
        {
            string sql = SqlCommands.GetUpdateSql("OrderCancelRecord", new string[] { "CancelStatus", "ValidationRemark", "AdminId", "AdminFullName", "CancelOrderTime" }, new string[] { "DriverId", "OrderNo" });
            DynamicParameters parameters = new DynamicParameters();
            if (!entity.DriverId.HasValue)
            {
                sql = SqlCommands.GetUpdateSql("OrderCancelRecord", new string[] { "CancelStatus", "ValidationRemark", "AdminId", "AdminFullName" }, new string[] { "OrderNo" });
            }
            else
            {
                parameters.Add("?DriverId", entity.DriverId, DbType.Int64, size: 20);
            }
            parameters.Add("?OrderNo", entity.OrderNo, DbType.AnsiString, size: 20);
            parameters.Add("?OrderCancelRecordId", entity.OrderCancelRecordId, DbType.Int64, size: 20);
            parameters.Add("?CancelStatus", OrderValidationStatus.Success.ToString(), DbType.AnsiString);
            parameters.Add("?ValidationRemark", entity.ValidationRemark, DbType.AnsiString, size: 400);
            parameters.Add("?CancelOrderTime", DateTime.Now, DbType.DateTime);
            parameters.Add("?AdminId", entity.AdminId, DbType.Int64, size: 20);
            parameters.Add("?AdminFullName", entity.AdminFullName, DbType.AnsiString, size: 400);
            sql = string.Format("{0} {1} WHERE OrderCancelRecordId=?OrderCancelRecordId", sql, QUERY_VIEW);
            return await this.databaseContext.Slave.QueryFirstOrDefaultAsync<OrderCancelRecordEntity>(sql, parameters);
        }
    }
}
